package fidel.permission.controller.interceptor;

import java.util.List;
import java.util.Objects;
import java.util.Set;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import fidel.permission.po.ActiveUser;
import fidel.permission.po.SysPermission;
import fidel.permission.util.ResourcesUtil;

/**
 * 
 * 权限拦截器
 * 
 * @author fidel
 * @date 2021年5月
 * @version 1.0
 */
public class AuthorizationInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        String method = request.getMethod(), servletPath = request.getServletPath(), loginPath = "/login.action";
        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/page/refuse.jsp");
        HttpSession session = request.getSession();
        ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
        // 获取可匿名访问的uri集合
        Set<String> set = ResourcesUtil.getKeys("anonymous");
        // 如果当前servlet路径与loginPath相同
        if (servletPath.equals(loginPath)) {
            // 请求的方式为post则放行，否则终止
            return method.equals("POST");
        }
        if (set.contains(servletPath)) {
            return true;
        }
        // 如果会话未存储ActiveUser实例
        if (Objects.isNull(activeUser)) {
            response.sendRedirect(request.getContextPath().concat(loginPath));
            return false;
        }
        // 获取公共uri集合
        set = ResourcesUtil.getKeys("common");
        // 如果uri集合中包含servletPath
        if (set.contains(servletPath)) {
            return true;
        }
        List<SysPermission> buttons = activeUser.getButtons();
        for (SysPermission button : buttons) {
            String uri = button.getUri();
            // servletPath是当前正在迭代的uri的子串，并且第一次在后者中首次出现的索引为0
            if (uri.indexOf(servletPath) == 0) {
                return true;
            }
        }
        dispatcher.forward(request, response);
        return false;
    }

    /*在执行handler返回modelAndView之前执行*/
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {
    }

    // 执行handler之后执行此方法
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {
    }

}
